/**
 * 
 */
package core;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import util.Constants;
import NET.sourceforge.BplusJ.BplusJ.BplusTree;

/**
 * Index Check Point data with a B-tree
 * 
 * @author Xiaohui TODO replace tree index on temporal dimension with hash
 */
public class CPDataIndexer implements Constants {

	final static String jndatasample = "17 519;0 922;1 670 381;27 305;26 346;";
	final static String sampleJid = "7249";
	List<String> cpdataList;
	String cpdata;
	BplusTree bpt;

	public CPDataIndexer(String checkPointData) throws Exception {
		this.cpdata = checkPointData;
		bpt = doIndex();
	}

	/**
	 * Expect check point data with format time_stamp1 obj_id_list1;time_stamp2
	 * obj_id_list2
	 * 
	 * @param cpdataList
	 * @throws Exception
	 */
	public CPDataIndexer(List<String> cpdataList) throws Exception {
		this.cpdataList = cpdataList;
		bpt = doIndexForJnList();
	}

	public CPDataIndexer() throws Exception {
	}

	private BplusTree doIndexForJnList() {
		return null;
	}

	// ===========================Used in loading raw data into btree
	public void creatBTree(String treeFile, String blockFile) throws Exception {
		String sampleKey = sampleJid + ",100";
		this.bpt = BplusTree.Initialize(treeFile, blockFile,
				sampleKey.length(), INVARIANTCULTUREID, nodesize, buffersize);
	}

	/**
	 * junction_id+time_point=>list_of_oid
	 * 
	 * @param jid
	 * @param cpString
	 * @throws Exception
	 */
	public void insert(int jid, String cpString) throws Exception {
		StringTokenizer st = new StringTokenizer(cpString, ";");
		String temp, timePoint, key, val;
		while (st.hasMoreElements()) {
			temp = st.nextToken();
			int k = temp.indexOf(" ");
			timePoint = temp.substring(0, k);
			key = jid + "," + timePoint;
			if (bpt.ContainsKey(key)) {
				val = bpt.get(key) + " " + temp.substring(k + 1);
			} else {
				val = temp.substring(k + 1);
			}
			bpt.Set(key, val); // jid,timepoint as key
		}

	}

	public void commitTree() throws Exception {
		this.bpt.Commit();
	}

	// =======================end here===============

	private BplusTree doIndexForList() throws Exception {
		BplusTree btree = BplusTree.Initialize(timsBTreeFile, timsBlockFile,
				sampleJid.length(), INVARIANTCULTUREID, nodesize, buffersize);
		for (String singleData : cpdataList) {
			StringTokenizer st = new StringTokenizer(singleData, ";");

			while (st.hasMoreElements()) {
				String temp = st.nextToken();
				int k = temp.indexOf(" ");
				String key = temp.substring(0, k);
				String val = temp.substring(k + 1);
				btree.Set(key, val);
			}
			btree.Commit();
		}
		return btree;
	}

	private BplusTree doIndex() throws Exception {
		StringTokenizer st = new StringTokenizer(cpdata, ";");
		BplusTree btree = BplusTree.Initialize(timsBTreeFile, timsBlockFile,
				sampleJid.length(), INVARIANTCULTUREID, nodesize, buffersize);
		while (st.hasMoreElements()) {
			String temp = st.nextToken();
			int k = temp.indexOf(" ");
			String key = temp.substring(0, k);
			String val = temp.substring(k + 1);
			btree.Set(key, val);
		}
		btree.Commit();
		return btree;
	}

	/**
	 * 
	 * @param minTime
	 * @param maxTime
	 * @return List of oids satisfying the time interval (minTime, maxTime)
	 * @throws Exception
	 */
	public List<String> getOids(double minTime, double maxTime)
			throws Exception {
		List<String> list = new LinkedList<String>();

		int i = 0;
		if (minTime != 0) {
			i = (int) minTime + 1;
		}
		for (; i <= (int) maxTime; i++) {
			if (bpt.ContainsKey(i + "")) {
				list.add(bpt.get(i + ""));
			}
		}

		return list;
	}

	/**
	 * 
	 * @param minTime
	 * @param maxTime
	 * @return List of oids satisfying the time interval (minTime, maxTime)
	 * @throws Exception
	 */
	public Set<Integer> getOidSet(double minTime, double maxTime)
			throws Exception {
		long start = System.currentTimeMillis();
		Set<Integer> oidset = new HashSet<Integer>();
		int i = 0;
		if (minTime != 0) {
			i = (int) minTime + 1;
		}
		System.out.println("Satisfied data...");
		for (; i <= (int) maxTime; i++) {
			if (bpt.ContainsKey(i + "")) {
				String value = bpt.get(i + "");
				// System.out.println(bpt.get(i+""));
				StringTokenizer st = new StringTokenizer(value, " ");
				while (st.hasMoreElements()) {
					oidset.add(Integer.parseInt(st.nextToken()));
				}
			}
		}
		long end = System.currentTimeMillis();
		System.err.println("Temporal Filtering(ms): " + (end - start));
		return oidset;
	}

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		CPDataIndexer idxer = new CPDataIndexer(jndatasample);
		List<String> ll = idxer.getOids(0, 15);
		for (String s : ll) {
			System.out.println(s);
		}

		// String temp = "hello world this is a test";
		// int k = temp.indexOf(" ");
		// String key = temp.substring(0, k);
		// String val = temp.substring(k + 1);
		// System.out.println(key);
		// System.out.println(val);
	}

}
